package com.example.admin.service.imp;

import com.alibaba.fastjson.JSONObject;
import com.example.admin.Dto.LoginDto;
import com.example.admin.Vo.UserVo;
import com.example.admin.bean.LoginUserDetails;
import com.example.admin.bean.User;
import com.example.admin.constants.RedisKeyConstants;
import com.example.admin.mapper.Usermapper;
import com.example.admin.service.Userservice;
import com.example.admin.utils.JwtUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class ImpUserservice implements Userservice {
    @Value("${zhyl.securet}")
    private String securitykey;
    @Value("${zhyl.expire}")
    private int dataoffset;
    @Autowired
    Usermapper usermapper;
    @Autowired
    @Lazy
    AuthenticationManager authenticationManager;
    @Autowired
    StringRedisTemplate redisTemplate;
    @Override
    public User findbyname(String name) {
        User user = usermapper.findbyname(name);
        return user;
    }

    @Override
    public UserVo login(LoginDto loginDto) throws Exception {
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
                new UsernamePasswordAuthenticationToken(loginDto.getUsername(),loginDto.getPassword());
        Authentication authenticate = authenticationManager.authenticate(usernamePasswordAuthenticationToken);
        if (!(authenticate.isAuthenticated())){
            throw new RuntimeException("登录失败");
        }
        System.out.println("认证成功");
//        拷贝userdetail对象的数据到uservo返回数据
        UserVo userVo = new UserVo();
        LoginUserDetails principal = (LoginUserDetails) authenticate.getPrincipal();
        Set<String> requestpaths = findresourceRequestPathsbyid(principal.getId());
        principal.setResourceRequestPaths(requestpaths);
        BeanUtils.copyProperties(principal,userVo);
//        生成token和uuid并存放在redis
        HashMap<String, Object> maps = new HashMap<>();

        String source = JSONObject.toJSONString(principal);
        maps.put("user",source);
        String token = JwtUtil.createJWT(securitykey, dataoffset,maps);
        String uuid = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set(RedisKeyConstants.LOGIN_USER_TOKEN+uuid,token,dataoffset, TimeUnit.SECONDS);
        redisTemplate.opsForValue().set(RedisKeyConstants.LOGIN_USER_UUID+principal.getUsername(),uuid,dataoffset,TimeUnit.SECONDS);
        //设置roleLabels，resourceRequestPaths还有token到uservo;
        Set<String> labels = findroleLabelsbyid(principal.getId());


        userVo.setResourceRequestPaths(requestpaths);
        userVo.setRoleLabels(labels);
        userVo.setUserToken(uuid);
        return userVo;
    }

    @Override
    public Set<String> findroleLabelsbyid(Long id) {
        Set<String> labels = usermapper.findroleLabelsbyid(id);
        return labels;
    }

    @Override
    public Set<String> findresourceRequestPathsbyid(Long id) {
        return usermapper.findresourceRequestPathsbyid(id);
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User findbyname = findbyname(username);
        LoginUserDetails loginUserDetails = new LoginUserDetails();
        BeanUtils.copyProperties(findbyname,loginUserDetails);
        System.out.println("进入了认证");
        return loginUserDetails;
    }
}
